﻿using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.SceneManagement;

public class GameManager : MonoBehaviour {

    //甜品的种类
    public enum SweetsType
    {
        EMPTY,
        NORMAL,
        BARRIER,
        ROW_CLEAR,
        COLUMN_CLEAR,
        RANBOWCANDY,
        COUNT//标记
    };
    public Dictionary<SweetsType, GameObject> sweetsDicts;
    [System.Serializable]
    public struct Sweet
    {
        public SweetsType type;
        public GameObject sweetPre;
    }

    public Sweet[] sweetPres;

    
    [SerializeField]
    private float startfilltime;
    [SerializeField]
    private float filltime;

    private static GameManager _instance;

    public static GameManager Instance
    {
        get
        {
            return _instance;
        }

        //set
        //{
        //    _instance = value;
        //}
    }



    public GameObject chocolatePrefab;
    public GameObject gameOverPanel;
    public Text gameOverScroe;
    public int xCollomn = 9;
    public int yRow = 9;

    //标记游戏结束
    private bool gameover;

    //UI 分数和时间
    private float countTime = 60f;

    public Text timeText;

    #region 分数字段
    private int score = 0;
    public int Score
    {
        get
        {
            return score;
        }

        set
        {
            score = value;
        }
    }
    private int currentScore = 0;
    private float scoreTime=0f;
    public Text scoreText;
    #endregion

    public GameSweets[,] m_sweets;

    private GameSweets switchSweet1;//交换的糖果1
    private GameSweets switchSweet2;//交换的糖果2

    private void Awake()
    {
        if (_instance == null)
        {
            _instance = this;
        }
    }
    // Use this for initialization
    void Start() {
       
        GameStartSet();
    }


    private void GameStartSet()
    {
        sweetsDicts = new Dictionary<SweetsType, GameObject>();
        m_sweets = new GameSweets[xCollomn, yRow];
        gameover = false;//游戏开始
        for (int i = 0; i < sweetPres.Length; i++)
        {
            if (!sweetsDicts.ContainsKey(sweetPres[i].type))
            {
                sweetsDicts.Add(sweetPres[i].type, sweetPres[i].sweetPre);
                //将糖果结构体数据加入到字典中
            }
        }
        for (int i = 0; i < xCollomn; i++)
        {
            for (int j = 0; j < yRow; j++)
            {

                CreateSweet(i, j, SweetsType.EMPTY);
            }
        }
        //test
        Destroy(m_sweets[4, 4].gameObject);
        GameObject gb = Instantiate(sweetsDicts[SweetsType.BARRIER], CorrectPosition(4, 4), Quaternion.identity);
        m_sweets[4, 4] = gb.GetComponent<GameSweets>();
        m_sweets[4, 4].Init(4, 4, SweetsType.BARRIER);


        if (chocolatePrefab != null)
        {
            for (int x = 0; x < xCollomn; x++)
            {
                for (int y = 0; y < yRow; y++)
                {
                    GameObject go = Instantiate(chocolatePrefab, CorrectPosition(x, y), Quaternion.identity);
                    go.transform.SetParent(this.transform);//实例化巧克力
                }
            }
        }
        StartCoroutine(AllFill(startfilltime));
        //AllFill();
    }

    private void Update()
    {
        //if (gameover)
        //{
        //    return;
        //}
        countTime -= Time.deltaTime;

        if (countTime <= 0)
        {
            countTime = 0;
            timeText.GetComponent<Animator>().SetBool("count", false);
            gameover = true;//游戏结束
            GameOver();
        }
        if ((int)countTime==10)
        {
            timeText.GetComponent<Animator>().SetBool("count",true);
        }
        if (scoreTime < 0.07f)
        {
            scoreTime += Time.deltaTime;
        }
        else
        {
            if (currentScore < score)
            {
                currentScore++;        
                scoreTime = 0f;            
                scoreText.text = currentScore.ToString("0");
            }
            
        }
        
        
        timeText.text = countTime.ToString("0");

    }



    public Vector3 CorrectPosition(int x,int y)
    {
        //从中心点开始减去总得一半再加上x，从中心点加上总得一般减去y
        return new Vector3(transform.position.x - xCollomn / 2f + x, transform.position.y + yRow / 2f - y,0);
    }



    public GameSweets CreateSweet(int x,int y,SweetsType _type)
    {
        GameObject gs = Instantiate(sweetsDicts[_type], CorrectPosition(x, y), Quaternion.identity);
        m_sweets[x, y] = gs.GetComponent<GameSweets>();
        m_sweets[x, y].Init(x, y, _type);
        return m_sweets[x, y];
    }


    public IEnumerator AllFill(float _filltime)
    {
        bool refill = true;
        while (refill)
        {
            yield return new WaitForSeconds(_filltime);
            while (Fill())
            {
                yield return new WaitForSeconds(_filltime);
            }
            refill = ClearFinishSweets();
        }
    }

    public bool Fill()
    {
        bool allFillNotFinish = false;

        for(int y = yRow - 2; y >= 0; y--)
        {
            for(int x = 0; x < xCollomn; x++)
            {
                GameSweets gs = m_sweets[x, y];//得到当前的糖果
                if (gs.CanMove())//判断是否可以移动
                {
                    GameSweets gsBellow = m_sweets[x, y + 1];
                    if (gsBellow.Type == SweetsType.EMPTY)//垂直填充
                    {
                        gs.m_MoveSweet.move(x, y + 1,filltime);//移动到空
                        m_sweets[x, y + 1] = gs;//赋值到下面的
                        CreateSweet(x, y, SweetsType.EMPTY);//将原来的变成空
                        allFillNotFinish = true;//有空的还没完成
                    }else //斜向填充 遍历左右下两边的情况
                    {
                        int downY = y + 1;
                        for(int dx = -1; dx <= 1; dx++)
                        {
                            if (dx!=0)
                            {
                                int downX = x + dx;
                                if (downX >= 0 && downX <= xCollomn - 1) //限制斜向范围x的值以防超过
                                {
                                    GameSweets obSweets = m_sweets[downX,downY];
                                    if (obSweets.Type == SweetsType.EMPTY)  //斜下为空
                                    {
                                        //斜下为空则  
                                        //1.需要填充
                                        //2.查看头上是不是不可以移动的
                                        GameSweets obAbSweets = m_sweets[downX, downY - 1];
                                        if (!obAbSweets.CanMove()) //头上不可以移动
                                        {
                                            //当前糖果往下移动
                                            gs.m_MoveSweet.move(downX, downY,filltime);//移动到该位置
                                            m_sweets[downX, downY] = gs;//将gamesweet 的值转移
                                            CreateSweet(x, y, SweetsType.EMPTY);//将原来的设置为空
                                            allFillNotFinish = true;//仍有空未完成
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }

        for(int x = 0; x < xCollomn; x++)
        {
            //最上排先生成糖果
            GameSweets sweet = m_sweets[x, 0];
            if (sweet.Type == SweetsType.EMPTY)
            {
                GameObject gs = Instantiate(sweetsDicts[SweetsType.NORMAL], CorrectPosition(x, -1), Quaternion.identity);//生成在y=-1的位置
                gs.transform.parent = transform;
                m_sweets[x, 0] = gs.GetComponent<GameSweets>();
                m_sweets[x, 0].Init(x, -1, SweetsType.NORMAL);
                m_sweets[x, 0].m_MoveSweet.move(x, 0,filltime);
                m_sweets[x, 0].m_ColorSweet.SetColor((ColorSweet.ColorType)Random.Range(0, (float)ColorSweet.ColorType.COUNT));
                allFillNotFinish = true;
            }
        }
        return allFillNotFinish;
    }

    private bool isNeighbor(GameSweets gs1,GameSweets gs2)
    {
        return (gs1.X == gs2.X && Mathf.Abs(gs1.Y - gs2.Y) == 1) || (gs1.Y == gs2.Y && Mathf.Abs(gs1.X - gs2.X) == 1);
    }



    public void Switch(GameSweets gs1,GameSweets gs2)
    {
        if (isNeighbor(gs1, gs2))
        {
            if (gs1.CanMove() && gs2.CanMove())
            {
                m_sweets[gs1.X, gs1.Y] = gs2;
                m_sweets[gs2.X, gs2.Y] = gs1;

                if (MatchSweet(gs1, gs2.X, gs2.Y) != null || MatchSweet(gs2, gs1.X, gs1.Y) != null || gs1.Type == SweetsType.RANBOWCANDY || gs2.Type == SweetsType.RANBOWCANDY || gs1.Type == SweetsType.COLUMN_CLEAR|| gs2.Type == SweetsType.COLUMN_CLEAR|| gs1.Type == SweetsType.ROW_CLEAR|| gs2.Type == SweetsType.ROW_CLEAR)
                {
                    int tempX = gs1.X;
                    int tempY = gs1.Y;

                    gs1.m_MoveSweet.move(gs2.X, gs2.Y, filltime);
                    gs2.m_MoveSweet.move(tempX, tempY, filltime);

                    if (gs1.Type == SweetsType.RANBOWCANDY && gs1.CanClear() && gs2.CanClear()) 
                    {
                        //设置消除的颜色
                        ClearColorSweet colorSweet = gs1.GetComponent<ClearColorSweet>();
                        if (colorSweet != null)
                        {
                            colorSweet.Color = gs2.m_ColorSweet.CurrentType;
                        }
                        ClearMatchSweets(gs1.X, gs1.Y);
                    }
                    if (gs2.Type == SweetsType.RANBOWCANDY && gs2.CanClear() && gs1.CanClear())
                    {
                        //设置消除的颜色
                        ClearColorSweet colorSweet = gs2.GetComponent<ClearColorSweet>();
                        if (colorSweet != null)
                        {
                            colorSweet.Color = gs1.m_ColorSweet.CurrentType;
                        }
                        ClearMatchSweets(gs2.X, gs2.Y);//调用
                    }


                    if ((gs1.Type == SweetsType.ROW_CLEAR||gs1.Type==SweetsType.COLUMN_CLEAR) && gs1.CanClear() && gs2.CanClear())
                    {
                                           
                        ClearMatchSweets(gs1.X, gs1.Y);
                    }
                    if ((gs2.Type == SweetsType.ROW_CLEAR || gs2.Type == SweetsType.COLUMN_CLEAR) && gs1.CanClear() && gs2.CanClear())
                    {
                       
                        ClearMatchSweets(gs2.X, gs2.Y);
                    }
                    ClearFinishSweets();
                    StartCoroutine(AllFill(filltime));

                    switchSweet1 = null;
                    switchSweet2 = null;//防止快速交换
                    


                }
                

                else
                {
                    m_sweets[gs1.X, gs1.Y] = gs1;
                    m_sweets[gs2.X, gs2.Y] = gs2;

                }
            }
        }
    }

    public void OnPressSweet(GameSweets gs)
    {
        if (gameover)
        {
            return;
        }
        //当前点击的甜品
        switchSweet1 = gs;
    }
    public void OnEnterSweet(GameSweets gs)
    {
        if (gameover)
        {
            return;
        }
        //与之挑换的甜品
        switchSweet2 = gs;
    }
    public void OnReleaseSweet()
    {
        if (gameover)
        {
            return;
        }
        Switch(switchSweet1, switchSweet2);
    }

    public List<GameSweets> MatchSweet(GameSweets sweet,int newX,int newY)
    {
        if (sweet.CanColor())
        {
            ColorSweet.ColorType color = sweet.m_ColorSweet.CurrentType;
            List<GameSweets> MatchRowSweets = new List<GameSweets>();//y
            List<GameSweets> MatchColumnSweets = new List<GameSweets>();//x
            List<GameSweets> FinishMatchSweets = new List<GameSweets>();//完成匹配的


            MatchColumnSweets.Add(sweet);
            //从左和右经行遍历  0向左 1向右
            for(int i = 0; i <= 1; i++)
            {
                for(int x = 1; x < xCollomn; x++)
                {
                    int m_x;
                    if (i == 0)
                    {
                        //向左
                        m_x = newX - x;
                        
                    }else
                    {
                        //向右
                        m_x = newX + x;
                       
                    }
                    if (m_x < 0 || m_x > xCollomn - 1)
                    {
                        break;
                    }
                    if (m_sweets[m_x, newY].CanColor() && m_sweets[m_x, newY].m_ColorSweet.CurrentType == color)//匹配出颜色
                    {
                        //添加进完成匹配列表
                        MatchColumnSweets.Add(m_sweets[m_x, newY]);
                    }else
                    {
                        break;//不允许不相邻的糖果不是一样的颜色种类
                    }
                }
            }

            if (MatchColumnSweets.Count >= 3)
            {
                
                for(int i = 0; i < MatchColumnSweets.Count; i++) //普通完成匹配
                {
                    FinishMatchSweets.Add(MatchColumnSweets[i]);
                    
                }

                //LT匹配
                for(int i = 0; i < MatchColumnSweets.Count; i++)
                {
                    //从上到下
                    for (int q = 0; q <= 1; q++)
                    {
                        for (int j = 1; j < yRow; j++)
                        {
                            int q_y;
                            if (q == 0)
                            {
                                q_y = newY - j;
                            }
                            else
                            {
                                q_y = newY + j;
                            }
                            if (q_y < 0 || q_y > yRow - 1)
                            {
                                break;
                            }
                            if ( m_sweets[MatchColumnSweets[i].X, q_y].CanColor() && m_sweets[MatchColumnSweets[i].X, q_y].m_ColorSweet.CurrentType == color )
                            {
                                MatchRowSweets.Add(m_sweets[MatchColumnSweets[i].X, q_y]);
                            }
                            else
                            {
                                break;
                            }
                        }
                    }
                    if (MatchRowSweets.Count < 2)
                    {
                        MatchRowSweets.Clear();
                    }
                    else
                    {
                        for (int w = 0; w < MatchRowSweets.Count; w++)
                        {
                            FinishMatchSweets.Add(MatchRowSweets[w]);
                        }
                        break;
                    }
                }

               


            }

            

            if (FinishMatchSweets.Count >= 3)
            {
                Debug.Log(FinishMatchSweets.Count);

                return FinishMatchSweets;
            }

            MatchRowSweets.Clear();
            MatchColumnSweets.Clear();
            FinishMatchSweets.Clear();



            MatchRowSweets.Add(sweet);
            //从上到下列遍历  
            for (int i = 0; i <= 1; i++)
            {
                for (int y = 1; y < yRow; y++)
                {
                    int m_y;
                    if (i == 0)
                    {
                        //向上
                        m_y = newY - y;
                        
                    }
                    else
                    {
                        //向下
                        m_y = newY + y;
                        
                    }
                    if (m_y < 0 || m_y > yRow - 1)
                    {
                        break;
                    }
                    if (m_sweets[newX,m_y].CanColor()&&m_sweets[newX, m_y].m_ColorSweet.CurrentType == color)//匹配出颜色
                    {
                        //添加进完成匹配列表
                        MatchRowSweets.Add(m_sweets[newX, m_y]);
                    }
                    else
                    {
                        break;//不允许不相邻的糖果不是一样的颜色种类
                    }
                }
            }

            if (MatchRowSweets.Count >= 3)
            {
                for (int i = 0; i < MatchRowSweets.Count; i++)
                {
                    FinishMatchSweets.Add(MatchRowSweets[i]);
                    
                }

                //LT匹配
                for (int i = 0; i < MatchRowSweets.Count; i++)
                {
                    //从上到下
                    for (int q = 0; q <= 1; q++)
                    {
                        for (int j = 1; j < xCollomn; j++)
                        {
                            int q_x;
                            if (q == 0)
                            {
                                q_x = newX - j;
                            }
                            else
                            {
                                q_x = newX + j;
                            }
                            if (q_x < 0 || q_x > xCollomn - 1)
                            {
                                break;
                            }
                            if ( m_sweets[q_x, MatchRowSweets[i].Y].CanColor() && m_sweets[q_x, MatchRowSweets[i].Y].m_ColorSweet.CurrentType == color )
                            {
                                MatchColumnSweets.Add(m_sweets[q_x, MatchRowSweets[i].Y]);
                            }
                            else
                            {
                                break;
                            }
                        }
                    }

                    if (MatchColumnSweets.Count < 2)
                    {
                        MatchColumnSweets.Clear();
                    }
                    else
                    {
                        for (int w = 0; w < MatchColumnSweets.Count; w++)
                        {
                            FinishMatchSweets.Add(MatchColumnSweets[w]);
                        }
                        break;
                    }
                }



            }

            

            if (FinishMatchSweets.Count >= 3)
            {
                return FinishMatchSweets;
            }
            else
            {
                return null;
            }



        }
        else
        {

            return null;
        }
    }

    /// <summary>
    /// 查看元素是否可以清除 如果可以清除则制空 并返回true
    /// </summary>
    /// <param name="x"></param>
    /// <param name="y"></param>
    /// <returns></returns>
    public bool ClearMatchSweets(int x,int y)
    {
        if (m_sweets[x, y].CanClear()&&!m_sweets[x,y].m_ClearSweet.IsClearing)
        {
            m_sweets[x, y].m_ClearSweet.Clear();
            CreateSweet(x, y, SweetsType.EMPTY);
            ClearBarrier(x, y);
            return true;
        }else
        {
            return false;
        }
    }


    //主要用于一开始有需要清除的
    public bool ClearFinishSweets()
    {
        bool needRefill = false;
        for(int x = 0; x < xCollomn; x++)
        {
            for (int y = 0; y < yRow; y++)
            {
                if (m_sweets[x, y].CanClear())
                {
                    List<GameSweets> matchSweets = MatchSweet(m_sweets[x, y], x, y);
                    if (matchSweets != null)
                    {
                        SweetsType specialType = SweetsType.COUNT;
                        //选择随机的位置作为特殊甜品的位置
                        GameSweets speacialSweet = matchSweets[Random.Range(0, matchSweets.Count)];
                        int specialX = speacialSweet.X;
                        int specialY = speacialSweet.Y;

                        if (matchSweets.Count == 4)
                        {
                            //随机生成行或列消除
                             specialType = (SweetsType)Random.Range((int)SweetsType.ROW_CLEAR, (int)SweetsType.COLUMN_CLEAR+1);
                        }else if (matchSweets.Count >= 5)
                        {
                            //生成彩虹
                             specialType = SweetsType.RANBOWCANDY;
                        }

                        for(int i = 0; i < matchSweets.Count; i++)
                        {
                            if (ClearMatchSweets(matchSweets[i].X, matchSweets[i].Y))
                            {
                                needRefill = true;
                            }
                        }

                        if (specialType!=SweetsType.COUNT)
                        {
                        //    //生成特殊
                            Destroy(m_sweets[specialX, specialY].gameObject);
                            
                            GameSweets newSpecial = CreateSweet(specialX, specialY, specialType);
                            if (specialType == SweetsType.ROW_CLEAR || specialType == SweetsType.COLUMN_CLEAR && newSpecial.CanColor())
                            {
                                newSpecial.m_ColorSweet.SetColor(ColorSweet.ColorType.PINK);
                            }
                            else if (specialType == SweetsType.RANBOWCANDY && newSpecial.CanColor())
                            {                      
                                newSpecial.m_ColorSweet.SetColor(ColorSweet.ColorType.COLOR);
                            }
                        }                   
                    }
                }
            }
        }
        return needRefill;
    }


    /// <summary>
    /// 清除列  y  
    /// </summary>
    public void ClearColomn(int _x)
    {
        for(int y = 0; y < yRow; y++)
        {
            ClearMatchSweets(_x, y);
        }
    }
    
    /// <summary>
    /// 清楚行  x
    /// </summary>
    public void ClearRow(int _y)
    {
        for (int x = 0; x < xCollomn; x++)
        {
            ClearMatchSweets(x, _y);
        }        
    }

    public void ClearColor(ColorSweet.ColorType color)
    {
        for(int x = 0; x < xCollomn; x++)
        {
            for(int y = 0; y < yRow; y++)
            {
                if(m_sweets[x,y].CanColor()&& (m_sweets[x, y].m_ColorSweet.CurrentType == color || color == ColorSweet.ColorType.COLOR))
                {
                    ClearMatchSweets(x, y);//清除同类型的糖果或者
                }
            }
        }
    }

    /// <summary>
    /// 清除障碍的方法
    /// </summary>
    /// <param name="x"></param>
    /// <param name="y"></param>
    public void ClearBarrier(int x, int y)
    {


        for (int i = -1; i <= 1; i++)//左右的情况
        {
            if (i == 0) continue;
            int newX = x + i;
            if (newX < 0 || newX >= xCollomn)   continue;
            if (m_sweets[newX, y].Type == SweetsType.BARRIER && m_sweets[newX, y].CanClear())
            {
                m_sweets[newX, y].m_ClearSweet.Clear();
                CreateSweet(newX, y, SweetsType.EMPTY);
                return;
            }
        }
        for (int j = -1; j <= 1; j++)
        {//上下的情况       
            if (j == 0) continue;
            int newY = y + j;
            if (newY < 0 || newY >= yRow) continue;
            if (m_sweets[x, newY].Type == SweetsType.BARRIER && m_sweets[x, newY].CanClear())
            {
                m_sweets[x, newY].m_ClearSweet.Clear();
                CreateSweet(x, newY, SweetsType.EMPTY);
                return;
            }
        }
    }

    /// <summary>
    /// 重新开始游戏
    /// </summary>
    public void Restart()
    {
        SceneManager.LoadScene(1);  //等于重新启动游戏
        //for (int i = 0; i < xCollomn; i++)
        //{
        //    for (int j = 0; j < yRow; j++)
        //    {

        //        Destroy(m_sweets[i, j].gameObject);
        //    }
        //}
        
        //sweetsDicts.Clear();
        //GameStartSet();
    }

    /// <summary>
    /// 返回主菜单
    /// </summary>
    public void BackToStart()
    {
        SceneManager.LoadScene(0);//返回开始菜单
    }


    /// <summary>
    /// 游戏结束
    /// </summary>
    public void GameOver()
    {
        if (gameover)
        {
            gameOverPanel.SetActive(true);
            gameOverScroe.text = currentScore.ToString();
        }
    }
}
